package com.lineage.server.datatables;

import java.lang.reflect.InvocationTargetException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.lineage.server.templates.L1SupperDoll;
import com.lineage.server.utils.PerformanceTimer;
import com.lineage.server.utils.SQLUtil;
import com.lineage.DatabaseFactory;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.doll.L1DollExecutor;
import com.lineage.server.serverpackets.S_PacketBoxThirdSpeed;
import com.lineage.server.templates.L1Doll;
import com.lineage.server.templates.L1Item;


public class SupperDollTable  {
	private static final Log _log = LogFactory.getLog(DollPowerTable.class);
	private static SupperDollTable _instance;

	private    HashMap<Integer, L1SupperDoll> _powerMap = new HashMap<Integer, L1SupperDoll>();
	private    HashMap<Integer, L1DollExecutor> _classList = new HashMap<Integer, L1DollExecutor>();
	private static  final ArrayList<String> _checkList = new ArrayList<String>();
 




	public static SupperDollTable get() {
		if (_instance == null) {
			_instance = new SupperDollTable();
		}
		return _instance;
	}
	

	public void load() {
		PerformanceTimer timer = new PerformanceTimer();
		Connection con = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			con = DatabaseFactory.get().getConnection();

			pstm = con.prepareStatement("SELECT * FROM `etcitem_doll_power`");

			rs = pstm.executeQuery();

			while (rs.next()) {
				int id = rs.getInt("id");
				String classname = rs.getString("classname");
				int type1 = rs.getInt("type1");
				int type2 = rs.getInt("type2");
				int type3 = rs.getInt("type3");
				String note = rs.getString("note");
				// 新增娃娃能力描述↓↓↓
				final int doll_ac = rs.getInt("ac");
				final int doll_str = rs.getInt("str");
				final int doll_dex = rs.getInt("dex");
				final int doll_con = rs.getInt("con");
				final int doll_intel = rs.getInt("int");
				final int doll_wis = rs.getInt("wis");
				final int doll_cha = rs.getInt("cha");
				final int doll_hp = rs.getInt("hp");
				final int doll_mp = rs.getInt("mp");
				final int doll_hpr = rs.getInt("hpr");
				final int doll_mpr = rs.getInt("mpr");
				final int doll_mr = rs.getInt("mr");
				final int doll_sp = rs.getInt("sp");
				final int doll_dmg = rs.getInt("dmg");
				final int doll_hit = rs.getInt("hit");
				final int doll_bowdmg = rs.getInt("bowdmg");
				final int doll_bowhit = rs.getInt("bowhit");
				final int doll_alldmg_r = rs.getInt("alldmg_r");
				final int doll_exp = rs.getInt("exp");
				final int doll_weight = rs.getInt("weight");
				final int doll_weight_r = rs.getInt("weight_r");
				final int doll_earth = rs.getInt("earth");
				final int doll_wind = rs.getInt("wind");
				final int doll_water = rs.getInt("water");
				final int doll_fire = rs.getInt("fire");
				final int doll_stun = rs.getInt("stun");
				final int doll_stone = rs.getInt("stone");
				final int doll_sleep = rs.getInt("sleep");
				final int doll_freeze = rs.getInt("freeze");
				final int doll_sustain = rs.getInt("sustain");
				final int doll_blind = rs.getInt("blind");
				final int doll_haste = rs.getInt("haste");
				final int doll_stunlv = rs.getInt("stunlv");
				final int doll_breaklv = rs.getInt("breaklv");
				final int doll_foeslayer = rs.getInt("foeslayer");
				final int doll_titanhp = rs.getInt("titanhp");
				// 新增娃娃能力描述↑↑↑
				String ch = classname + "=" + type1 + "=" + type2 + "=" + type3 + "=" + note;
				if (_checkList.lastIndexOf(ch) == -1) {
					_checkList.add(ch);
					//addList(id, classname, type1, type2, type3, note);
					// 新增娃娃能力描述↓↓↓
					addList(id, classname, type1, type2, type3, note,
							doll_ac,
							doll_str,
							doll_dex,
							doll_con,
							doll_intel,
							doll_wis,
							doll_cha,
							doll_hp,
							doll_mp,
							doll_hpr,
							doll_mpr,
							doll_mr,
							doll_sp,
							doll_dmg,
							doll_hit,
							doll_bowdmg,
							doll_bowhit,
							doll_alldmg_r,
							doll_exp,
							doll_weight,
							doll_weight_r,
							doll_earth,
							doll_wind,
							doll_water,
							doll_fire,
							doll_stun,
							doll_stone,
							doll_sleep,
							doll_freeze,
							doll_sustain,
							doll_blind,
							doll_haste,
							doll_stunlv,
							doll_breaklv,
							doll_foeslayer,
							doll_titanhp
							);
					// 新增娃娃能力描述↑↑↑
				} else {
					_log.error("娃娃能力设计重复:id=" + id + " type1=" + type1 + " type2=" + type2 + " type3=" + type3);
				}
			}
		} catch (SQLException e) {
			_log.error(e.getLocalizedMessage(), e);
		} catch (Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		} finally {
			SQLUtil.close(rs);
			SQLUtil.close(pstm);
			SQLUtil.close(con);
			
			_checkList.clear();
		}
		_log.info("读取->娃娃能力资料数量: " + _classList.size() + "(" + timer.get() + "ms)");
		setSupperDollType();
	}
	
	



	
	public void setSupperDollType() {
		PerformanceTimer timer = new PerformanceTimer();
		Connection con = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			con = DatabaseFactory.get().getConnection();

			pstm = con.prepareStatement("SELECT * FROM `etcitem_supper_doll_type`");

			rs = pstm.executeQuery();

			while (rs.next()) {
				int itemobjid = rs.getInt("itemobjid");
				int itemid = rs.getInt("itemid");
				String dollPowers = rs.getString("powers").replaceAll(" ", "");	
				String need = rs.getString("need").replaceAll(" ", "");
				String count = rs.getString("count").replaceAll(" ", "");
				int time = rs.getInt("time");
				int gfxid = rs.getInt("gfxid");
				String nameid = rs.getString("nameid");
				

				boolean iserr = false;
				ArrayList<L1DollExecutor> powerList = new ArrayList<L1DollExecutor>();
				if ((dollPowers != null) && (!dollPowers.equals(""))) {
					String[] dollPowerSet1 = dollPowers.split(",");
					for (String string : dollPowerSet1) {
						L1DollExecutor e = (L1DollExecutor)_classList.get(Integer.valueOf(Integer.parseInt(string)));
						if (e != null) {
							//这里添加娃娃的能力值
							powerList.add(e);
						} else {
							_log.error("娃娃能力读取错误-没有这个编号:" + string);
							iserr = true;
						}
					}
				}
				
				iserr = false;
				int[] needs = (int[]) null;
				if ((need != null) && (!need.equals(""))) {
					String[] set2 = need.split(",");
					needs = new int[set2.length];
					for (int i = 0; i < set2.length; i++) {
						int itemid_n = Integer.parseInt(set2[i]);

						L1Item temp = ItemTable.get().getTemplate(itemid_n);
						if (temp == null) {
							_log.error("娃娃能力读取错误-没有这个编号:" + itemid_n);
							iserr = true;
						}
						needs[i] = itemid_n;
					}
				}
				
				iserr = false;
				int[] counts = (int[]) null;
				if ((count != null) && (!count.equals(""))) {
					String[] set3 = count.split(",");
					counts = new int[set3.length];
					if (set3.length != needs.length) {
						_log.error("物品咨询对应错误: itemid:" + itemid);
						iserr = true;
					}

					for (int i = 0; i < set3.length; i++) {
						int count_n = Integer.parseInt(set3[i]);
						counts[i] = count_n;
					}

				}

				if (!iserr) {
					L1SupperDoll spdoll_power = new L1SupperDoll();
					spdoll_power.setItemobjid(itemobjid);
					spdoll_power.set_itemid(itemid);
					spdoll_power.setPowerList(powerList);
					spdoll_power.set_need(needs);
					spdoll_power.set_counts(counts);
					spdoll_power.set_time(time);
					spdoll_power.set_gfxid(gfxid);
					spdoll_power.set_nameid(nameid);
					_powerMap.put(Integer.valueOf(itemobjid), spdoll_power);
					
				}
			}

		} catch (SQLException e) {
			_log.error(e.getLocalizedMessage(), e);
		} catch (Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		} finally {
			SQLUtil.close(rs);
			SQLUtil.close(pstm);
			SQLUtil.close(con);
//			_classList.clear();
		}
		_log.info("读取->supper娃娃能力资料数量: " + _classList.size() + "(" + timer.get() + "ms)");
	}
	
	
	
	public void update( int olditemobjid,int itemobjid, String s) {
		Connection cn = null;
		PreparedStatement ps = null;
		try {
			cn = DatabaseFactory.get().getConnection();
			ps = cn.prepareStatement("UPDATE `etcitem_supper_doll_type` SET powers=? ,`itemobjid`=? WHERE `itemobjid`=?");
			ps.setString(1, s);
			ps.setInt(2, itemobjid);
			ps.setInt(3, olditemobjid);
			ps.execute();
		} catch (Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		} finally {
			SQLUtil.close(ps);
			SQLUtil.close(cn);
		}
		

	}
	
	public void runInsert( int itemObjId,int itemid, L1PcInstance pc,String s,int gfxid,String nameid) {
		Connection cn = null;
		PreparedStatement ps = null;
		try {
			cn = DatabaseFactory.get().getConnection();
			ps = cn.prepareStatement("INSERT INTO `etcitem_supper_doll_type` SET itemobjid=?,itemid=?,powers =?,need=?,count=?,time=?,gfxid=?,nameid=?");
			ps.setInt(1, itemObjId);
			ps.setInt(2, itemid);
			ps.setString(3, s);
			ps.setString(4, "41246");
			ps.setString(5, "100");
			ps.setInt(6, 1800);
			ps.setInt(7, gfxid);
			ps.setString(8, nameid);
			ps.execute();
		} catch (Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		} finally {
			SQLUtil.close(ps);
			SQLUtil.close(cn);
		}
		boolean iserr = false;
		String dollPowers = s.replaceAll(" ", "");	
		ArrayList<L1DollExecutor> powerList = new ArrayList<L1DollExecutor>();
		if ((dollPowers != null) && (!dollPowers.equals(""))) {
			String[] dollPowerSet1 = dollPowers.split(",");
			for (String string : dollPowerSet1) {

				L1DollExecutor e =  (L1DollExecutor) _classList.get(Integer.valueOf(Integer.parseInt(string)));
				if (e != null) {
					//这里添加娃娃的能力值
					powerList.add(e);
				} else {
					_log.error("娃娃能力读取错误-没有这个编号:" + string);
				}
			}
		}
		
		
		if (!iserr) {
		L1SupperDoll spdoll_power = new L1SupperDoll();
		spdoll_power.setItemobjid(itemObjId);
		spdoll_power.set_itemid(itemid);
		spdoll_power.setPowerList(powerList);
		int needsInt[] = {40146};
		spdoll_power.set_need(needsInt);
		int counts[] = {100};
		spdoll_power.set_counts(counts);
		spdoll_power.set_time(1800);
		spdoll_power.set_gfxid(gfxid);
		spdoll_power.set_nameid(nameid);
		_powerMap.put(Integer.valueOf(itemObjId), spdoll_power);
		}
		
	}
	
	public void runDelete(final int itemobjid) {
		Connection cn = null;
		PreparedStatement ps = null;
		try {
			cn = DatabaseFactory.get().getConnection();
			ps = cn.prepareStatement("Delete from `doll_power_supper` WHERE `itemid`=?");
			ps.setInt(1, itemobjid);
			ps.execute();
		} catch (Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		} finally {
			SQLUtil.close(ps);
			SQLUtil.close(cn);
		}
	}
	
	
	
	private void addList(final int powerid, final String className, final int type1, final int type2, final int type3,
			final String note,
			final int doll_ac,
			final int doll_str,
			final int doll_dex,
			final int doll_con,
			final int doll_intel,
			final int doll_wis,
			final int doll_cha,
			final int doll_hp,
			final int doll_mp,
			final int doll_hpr,
			final int doll_mpr,
			final int doll_mr,
			final int doll_sp,
			final int doll_dmg,
			final int doll_hit,
			final int doll_bowdmg,
			final int doll_bowhit,
			final int doll_alldmg_r,
			final int doll_exp,
			final int doll_weight,
			final int doll_weight_r,
			final int doll_earth,
			final int doll_wind,
			final int doll_water,
			final int doll_fire,
			final int doll_stun,
			final int doll_stone,
			final int doll_sleep,
			final int doll_freeze,
			final int doll_sustain,
			final int doll_blind,
			final int doll_haste,
			final int doll_stunlv,
			final int doll_breaklv,
			final int doll_foeslayer,
			final int doll_titanhp
			) {
		// 新增娃娃能力描述↑↑↑
		if (className.equals("0"))
			return;
		try {
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append("com.lineage.server.model.doll.");
			stringBuilder.append(className);

			final Class<?> cls = Class.forName(stringBuilder.toString());
			final L1DollExecutor exe = (L1DollExecutor) cls.getMethod("get").invoke(null);
			exe.set_power(type1, type2, type3);
			exe.set_note(note);
			// 新增娃娃能力描述↓↓↓
			exe.setDollAc(doll_ac);
			exe.setDollStr(doll_str);
			exe.setDollDex(doll_dex);
			exe.setDollCon(doll_con);
			exe.setDollInt(doll_intel);
			exe.setDollWis(doll_wis);
			exe.setDollCha(doll_cha);
			exe.setDollHp(doll_hp);
			exe.setDollMp(doll_mp);
			exe.setDollHpr(doll_hpr);
			exe.setDollMpr(doll_mpr);
			exe.setDollMr(doll_mr);
			exe.setDollSp(doll_sp);
			exe.setDollDmg(doll_dmg);
			exe.setDollHit(doll_hit);
			exe.setDollBowDmg(doll_bowdmg);
			exe.setDollBowHit(doll_bowhit);
			exe.setDollAllDmg_R(doll_alldmg_r);
			exe.setDollExp(doll_exp);
			exe.setDollWeight(doll_weight);
			exe.setDollWeight_R(doll_weight_r);
			exe.setDollEarth(doll_earth);
			exe.setDollWind(doll_wind);
			exe.setDollWater(doll_water);
			exe.setDollFire(doll_fire);
			exe.setDollStun(doll_stun);
			exe.setDollStone(doll_stone);
			exe.setDollSleep(doll_sleep);
			exe.setDollFreeze(doll_freeze);
			exe.setDollSustain(doll_sustain);
			exe.setDollBlind(doll_blind);
			exe.setDollHaste(doll_haste);
			exe.setDollStunLv(doll_stunlv);
			exe.setDollBreakLv(doll_breaklv);
			exe.setDollFoeSlayer(doll_foeslayer);
			exe.setDollTiTanHp(doll_titanhp);
			// 新增娃娃能力描述↑↑↑

			_classList.put(new Integer(powerid), exe);
		} catch (ClassNotFoundException e) {
			String error = "发生[娃娃能力档案]错误, 检查档案是否存在:" + className + " 娃娃能力编号:" + powerid;
			_log.error(error);
		} catch (IllegalArgumentException e) {
			_log.error(e.getLocalizedMessage(), e);
		} catch (IllegalAccessException e) {
			_log.error(e.getLocalizedMessage(), e);
		} catch (InvocationTargetException e) {
			_log.error(e.getLocalizedMessage(), e);
		} catch (SecurityException e) {
			_log.error(e.getLocalizedMessage(), e);
		} catch (NoSuchMethodException e) {
			_log.error(e.getLocalizedMessage(), e);
		}
	}




	
	public HashMap<Integer, L1DollExecutor> get_classList(){
		return _classList;
	}

	
	
	public HashMap<Integer, L1SupperDoll> get_powerMap(){
		return _powerMap;
	}
	

	
	public L1SupperDoll get_type(int itemobjid) {
		return (L1SupperDoll) _powerMap.get(Integer.valueOf(itemobjid));
	}

	public HashMap<Integer, L1SupperDoll> map() {
		return _powerMap;
	}
	


	

}
